/**
 * 中文日期封装 (zh-date.js)
 * 支持日期时间操作、链式调用、格式化、运算、比较
 * ES6+ 原生 Date 方法 + 中文命名 + JSDoc 参数提示
 */

class 日期 {
  /**
   * 构造函数 - 创建日期实例
   * @param {Date|string|number} [值=new Date()] 初始日期，可为 Date 实例、时间戳或日期字符串
   */
  constructor(值 = new Date()) {
    if (值 instanceof Date) {
      this._值 = new Date(值.getTime());
    } else {
      this._值 = new Date(值);
    }
  }

  /**
   * 获取原始 Date 对象的副本
   * @returns {Date} 日期对象的副本
   */
  取值() {
    return new Date(this._值.getTime());
  }

  /**
   * 获取年份
   * @returns {number} 年份值（四位数）
   */
  取年份() {
    return this._值.getFullYear();
  }

  /**
   * 设置年份，返回新日期（不修改原日期）
   * @param {number} 年 目标年份
   * @returns {日期} 新的日期实例
   */
  设年份(年) {
    const 新日期 = new Date(this._值.getTime());
    新日期.setFullYear(年);
    return new 日期(新日期);
  }

  /**
   * 获取月份
   * @returns {number} 月份值 (0-11，0表示1月)
   */
  取月份() {
    return this._值.getMonth();
  }

  /**
   * 设置月份，返回新日期（不修改原日期）
   * @param {number} 月 目标月份 (0-11，0表示1月)
   * @returns {日期} 新的日期实例
   */
  设月份(月) {
    const 新日期 = new Date(this._值.getTime());
    新日期.setMonth(月);
    return new 日期(新日期);
  }

  /**
   * 获取日期
   * @returns {number} 日期值 (1-31)
   */
  取日期() {
    return this._值.getDate();
  }

  /**
   * 设置日期，返回新日期（不修改原日期）
   * @param {number} 日 目标日期 (1-31)
   * @returns {日期} 新的日期实例
   */
  设日期(日) {
    const 新日期 = new Date(this._值.getTime());
    新日期.setDate(日);
    return new 日期(新日期);
  }

  /**
   * 获取小时
   * @returns {number} 小时值 (0-23)
   */
  取小时() {
    return this._值.getHours();
  }

  /**
   * 设置小时，返回新日期（不修改原日期）
   * @param {number} 小时 目标小时 (0-23)
   * @returns {日期} 新的日期实例
   */
  设小时(小时) {
    const 新日期 = new Date(this._值.getTime());
    新日期.setHours(小时);
    return new 日期(新日期);
  }

  /**
   * 获取分钟
   * @returns {number} 分钟值 (0-59)
   */
  取分钟() {
    return this._值.getMinutes();
  }

  /**
   * 设置分钟，返回新日期（不修改原日期）
   * @param {number} 分 目标分钟 (0-59)
   * @returns {日期} 新的日期实例
   */
  设分钟(分) {
    const 新日期 = new Date(this._值.getTime());
    新日期.setMinutes(分);
    return new 日期(新日期);
  }

  /**
   * 获取秒
   * @returns {number} 秒值 (0-59)
   */
  取秒() {
    return this._值.getSeconds();
  }

  /**
   * 设置秒，返回新日期（不修改原日期）
   * @param {number} 秒 目标秒 (0-59)
   * @returns {日期} 新的日期实例
   */
  设秒(秒) {
    const 新日期 = new Date(this._值.getTime());
    新日期.setSeconds(秒);
    return new 日期(新日期);
  }

  /**
   * 获取毫秒
   * @returns {number} 毫秒值 (0-999)
   */
  取毫秒() {
    return this._值.getMilliseconds();
  }

  /**
   * 设置毫秒，返回新日期（不修改原日期）
   * @param {number} ms 目标毫秒 (0-999)
   * @returns {日期} 新的日期实例
   */
  设毫秒(ms) {
    const 新日期 = new Date(this._值.getTime());
    新日期.setMilliseconds(ms);
    return new 日期(新日期);
  }

  /**
   * 获取星期几
   * @returns {number} 星期值 (0-6，0表示星期日)
   */
  周几() {
    return this._值.getDay();
  }

  /**
   * 获取时间戳
   * @returns {number} 时间戳（毫秒）
   */
  取时间戳() {
    return this._值.getTime();
  }

  /**
   * 获取ISO格式的字符串
   * @returns {string} ISO格式的日期字符串
   */
  ISO字符串() {
    return this._值.toISOString();
  }

  /**
   * 获取本地格式的字符串
   * @param {string|string[]} [本地] 地区代码
   * @param {Object} [选项={}] 格式化选项
   * @returns {string} 本地格式的日期字符串
   */
  本地字符串(本地 = undefined, 选项 = {}) {
    return this._值.toLocaleString(本地, 选项);
  }

  /**
   * 格式化日期为字符串
   * @param {string} [模板='YYYY-MM-DD HH:mm:ss'] 格式化模板
   * @returns {string} 格式化后的日期字符串
   */
  格式化(模板 = 'YYYY-MM-DD HH:mm:ss') {
    const pad = (n) => n.toString().padStart(2, '0');
    const 年 = this.取年份();
    const 月 = pad(this.取月份() + 1);
    const 日 = pad(this.取日期());
    const 时 = pad(this.取小时());
    const 分 = pad(this.取分钟());
    const 秒 = pad(this.取秒());
    return 模板.replace('YYYY', 年)
                .replace('MM', 月)
                .replace('DD', 日)
                .replace('HH', 时)
                .replace('mm', 分)
                .replace('ss', 秒);
  }

  /**
   * 日期加天数，返回新日期（不修改原日期）
   * @param {number} 天 要加的天数
   * @returns {日期} 新的日期实例
   */
  加天数(天) {
    const 新日期 = new Date(this._值.getTime());
    新日期.setDate(新日期.getDate() + 天);
    return new 日期(新日期);
  }

  /**
   * 日期减天数，返回新日期（不修改原日期）
   * @param {number} 天 要减的天数
   * @returns {日期} 新的日期实例
   */
  减天数(天) {
    return this.加天数(-天);
  }

  /**
   * 日期加月数，返回新日期（不修改原日期）
   * @param {number} 月数 要加的月数
   * @returns {日期} 新的日期实例
   */
  加月(月数) {
    const 新日期 = new Date(this._值.getTime());
    新日期.setMonth(新日期.getMonth() + 月数);
    return new 日期(新日期);
  }

  /**
   * 日期减月数，返回新日期（不修改原日期）
   * @param {number} 月数 要减的月数
   * @returns {日期} 新的日期实例
   */
  减月(月数) {
    return this.加月(-月数);
  }

  /**
   * 日期加年数，返回新日期（不修改原日期）
   * @param {number} 年数 要加的年数
   * @returns {日期} 新的日期实例
   */
  加年(年数) {
    const 新日期 = new Date(this._值.getTime());
    新日期.setFullYear(新日期.getFullYear() + 年数);
    return new 日期(新日期);
  }

  /**
   * 日期减年数，返回新日期（不修改原日期）
   * @param {number} 年数 要减的年数
   * @returns {日期} 新的日期实例
   */
  减年(年数) {
    return this.加年(-年数);
  }

  /**
   * 判断当前日期是否在指定日期之前
   * @param {Date|string|number|日期} 其他日期 要比较的日期
   * @returns {boolean} 是否在之前
   */
  是否在之前(其他日期) {
    const d = 其他日期 instanceof 日期 ? 其他日期._值 : new Date(其他日期);
    return this._值.getTime() < d.getTime();
  }

  /**
   * 判断当前日期是否在指定日期之后
   * @param {Date|string|number|日期} 其他日期 要比较的日期
   * @returns {boolean} 是否在之后
   */
  是否在之后(其他日期) {
    const d = 其他日期 instanceof 日期 ? 其他日期._值 : new Date(其他日期);
    return this._值.getTime() > d.getTime();
  }

  /**
   * 判断当前日期是否与指定日期相等
   * @param {Date|string|number|日期} 其他日期 要比较的日期
   * @returns {boolean} 是否相等
   */
  是否相等(其他日期) {
    const d = 其他日期 instanceof 日期 ? 其他日期._值 : new Date(其他日期);
    return this._值.getTime() === d.getTime();
  }

  /** 静态方法 */

  /**
   * 静态方法：获取当前日期
   * @static
   * @returns {日期} 当前日期实例
   */
  static 当前() {
    return new 日期(new Date());
  }

  /**
   * 静态方法：解析日期
   * @static
   * @param {Date|string|number} 值 要解析的日期值
   * @returns {日期} 解析后的日期实例
   */
  static 解析(值) {
    return new 日期(new Date(值));
  }

  /**
   * 静态方法：比较两个日期
   * @static
   * @param {Date|string|number|日期} a 第一个日期
   * @param {Date|string|number|日期} b 第二个日期
   * @returns {number} 比较结果（-1：a在b之前，0：相等，1：a在b之后）
   */
  static 比较(a, b) {
    const ta = a instanceof 日期 ? a._值.getTime() : new Date(a).getTime();
    const tb = b instanceof 日期 ? b._值.getTime() : new Date(b).getTime();
    return ta === tb ? 0 : ta < tb ? -1 : 1;
  }
}



// CommonJS 导出

  module.exports = {
    日期,
    default: 日期
  };
  module.exports.日期 = 日期;


// ES 模块导出
// export { 日期 };
// export default 日期;